package com.zwcl.glass.tools.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zwcl.common.core.domain.entity.ApiResult;
import com.zwcl.common.core.enums.ExceptionCode;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.common.core.redis.RedisLock;
import com.zwcl.glass.tools.entity.ContentRead;
import com.zwcl.glass.tools.mapper.ContentReadMapper;
import com.zwcl.glass.tools.service.ContentReadService;
import com.zwcl.common.mybatis.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Wrapper;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xieyongping
 * @since 2021-01-11
 */
@Service
public class ContentReadServiceImpl extends BaseServiceImpl<ContentReadMapper, ContentRead> implements ContentReadService {

    @Autowired
    private ContentReadMapper contentReadMapper;

    @Autowired
    private RedisLock redisLock;

    private final String contentReadRedisLockKey="RedisLock:Content:Read:";

    /**
     * 每次判断文章id是否存在的话，可能效率极低
     * 要带上readId
     * @param contentRead
     * @return
     */
    @Override
    public Boolean saveContentReadCount(ContentRead contentRead) {
        return contentReadMapper.saveContentReadCount(contentRead);
    }

    @Override
    public ContentRead getContentReadById(Long contentId,Integer contentType) {
        return getOne(new LambdaQueryWrapper<ContentRead>().eq(ContentRead::getContentId,contentId).eq(ContentRead::getContentType,contentType));
    }

    @Override
    public Boolean saveContentOperation(ContentRead contentRead) {
        String lockKey=contentReadRedisLockKey+contentRead.getContentId()+"|"+contentRead.getContentType();
        try {
            Boolean flag=true;
            //TODO:高并发下，如果contentId容易重复的话，可能还要加上contentType
            if(redisLock.tryLock(lockKey,60*1000L)) {
                if (null != contentRead.getId()) {
                    flag = saveContentReadCount(contentRead);
                } else {
                    ContentRead dbContentRead = getContentReadById(contentRead.getContentId(),contentRead.getContentType());
                    if (null != dbContentRead) {
                        contentRead.setId(dbContentRead.getId());
                        flag = saveContentReadCount(contentRead);
                    } else {
                        if (contentRead.getLikeNum() < 0 || contentRead.getReadNum() < 0) {
                            throw new BusinessException("参数数据不能<0");
                        }
                        flag = save(contentRead);
                    }
                }
                return flag;
            }else {
                return false;
            }
        }catch (Exception ex){
            log.error("更新文章操作信息失败:{}",ex);
            return false;
        }finally {
            redisLock.unlock(lockKey);
        }
    }

    @Override
    public List<ContentRead> batchGetContentRead(List<Integer> idList, Integer contentType) {
        return  list(new LambdaQueryWrapper<ContentRead>().in(ContentRead::getContentId,idList).eq(ContentRead::getContentType,contentType));
    }


}
